import dayjs from "dayjs";

const FORMAT_STR = "YYYY-MM-DD HH:mm:ss";
const LEVEL_STYLE = "border-radius: 4px;color: white;padding: 2px 4px;font-weight: 400;";

export enum LoggerLevel { // 位置越靠下，限制越松
    ERROR = "ERROR",
    INFO = "INFO",
    WARN = "WARN",
    DEBUG = "DEBUG",
}

export default class AppLogger {
    private loggerLevel: Required<LoggerLevel> = LoggerLevel.INFO;

    constructor(loggerLevel?: LoggerLevel) {
        this.loggerLevel = loggerLevel;
    }

    private logOutput(loggerLevel: LoggerLevel, levelStyle: string, msg: string, ...subst: any[]): void {
        // 日志级别
        const loggerLevelArr = [LoggerLevel.DEBUG, LoggerLevel.WARN, LoggerLevel.INFO, LoggerLevel.ERROR];
        const curLoggerLevel = loggerLevelArr.indexOf(loggerLevel);
        const envLoggerLevel = loggerLevelArr.indexOf(this.loggerLevel);
        const canOutput = curLoggerLevel >= envLoggerLevel;
        if (!canOutput) return;

        // 日志前缀
        const now = dayjs().format(FORMAT_STR);
        const loggerPrefix = `%c${now} %c${loggerLevel}%c `;

        // 占位符替换
        const replaceMsg = msg.replaceAll("{}", "%o");

        // 打印日志
        console.groupCollapsed(
            loggerPrefix + replaceMsg,
            "font-weight: 400",
            levelStyle + LEVEL_STYLE,
            "font-weight: 400",
            ...subst
        );
        console.trace();
        console.groupEnd();
    };

    error(msg: string, ...subst: any[]): void {
        const loggerLevel = LoggerLevel.ERROR;
        const levelStyle = "background-color: rgb(255,59,48);"
        this.logOutput(loggerLevel, levelStyle, msg, subst);
    };

    info(msg: string, ...subst: any[]): void {
        const loggerLevel = LoggerLevel.INFO;
        const levelStyle = "background-color: rgb(0, 122, 255);"
        this.logOutput(loggerLevel, levelStyle, msg, subst);
    };

    warn(msg: string, ...subst: any[]): void {
        const loggerLevel = LoggerLevel.WARN;
        const levelStyle = "background-color: rgb(255,149,0);"
        this.logOutput(loggerLevel, levelStyle, msg, subst);
    };

    debug(msg: string, ...subst: any[]): void {
        const loggerLevel = LoggerLevel.DEBUG;
        const levelStyle = "background-color: rgb(142,142,147);"
        this.logOutput(loggerLevel, levelStyle, msg, subst);
    };
}
